package com.jeesit.cloud.spot.business.impl.Impl;

import com.jeesit.cloud.dto.*;
import com.jeesit.cloud.model.*;
import com.jeesit.cloud.spot.business.impl.IContractBiz;
import com.jeesit.cloud.spot.service.*;
import com.jeesit.cloud.util.DateUtil;
import com.jeesit.cloud.util.DecimalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ContractBizImpl implements IContractBiz {

    @Autowired
    private IContractService contractService;
    @Autowired
    private IContractFinanceService contractFinanceService;
    @Autowired
    private IContractPendingOrderService contractPendingOrderService;
    @Autowired
    private IContractDetailService contractDetailService;
    @Autowired
    private IContractDetailRecordService contractDetailRecordService;
    @Autowired
    private IContractStorageService contractStorageService;
    @Autowired
    private IHedgingSchemeService hedgingSchemeService;
    @Autowired
    private IHedgingSchemeInstService hedgingSchemeInstService;
    @Autowired
    private IHedgeSchemeAccountService hedgeSchemeAccountService;
    @Autowired
    private IContractSchemaService contractSchemaService;

    /**
     * 添加、编辑合同
     * @param user
     * @param id
     * @param entity
     * @return
     */
    @Override
    @Transactional
    public JSONResult<Contract> saveData(User user, Long id, ContractDto entity) {
        ContractDto contractDto = new ContractDto();
        contractDto.setContractNumbers(entity.getContractNumber());
        List<Contract> contracts = contractService.list(1, contractDto);
        Contract it = new Contract();
        if(id==null){
            Assert.isTrue(contracts.size()==0,"合同编号已存在，请核对后重新输入");
            it.setAddUserName(user.getNickName());
            it.setAddUserUuid(user.getId());
            it.setAddTime(new Date());
            it.setDeleted(false);
        }else {
            Assert.isTrue(contracts.size()==0||contracts.get(0).getUuid().equals(id),"合同编号已存在，请核对后重新输入");
            it=contractService.getById(id);
            it.setModTime(new Date());
            it.setModUserUuid(user.getId());
            it.setModUserName(user.getNickName());
        }
        it.setSubmitState(entity.getSubmitState());
        it.setFiscalYear(entity.getFiscalYear());
        it.setIsContract(entity.getIsContract());
        it.setContractNumber(entity.getContractNumber());
        it.setContractNumberExternal(entity.getContractNumberExternal());
        it.setContractType(entity.getContractType());
        it.setPurShortname(entity.getPurShortname());
        it.setPurUuid(entity.getPurUuid());
        it.setSellShortname(entity.getSellShortname());
        it.setSellUuid(entity.getSellUuid());
        it.setContractDate(entity.getContractDate());
        it.setCatalogName(entity.getCatalogName());
        it.setCatalogUuid(entity.getCatalogUuid());
        it.setContractStatus(entity.getContractStatus());
        it.setOpenStatus(entity.getOpenStatus());
        it.setBizOrgName(entity.getBizOrgName());
        it.setBizOrgUuid(entity.getBizOrgUuid());
        it.setSalesmanName(entity.getSalesmanName());
        it.setSalesmanUuid(entity.getSalesmanUuid());
        it.setWeight(entity.getWeight());
        it.setContractAmount(entity.getContractAmount());
        it.setCheckStatus(0);
        it.setCheckTime(entity.getCheckTime());
        it.setCheckUserName(entity.getCheckUserName());
        it.setCheckUserUuid(entity.getCheckUserUuid());
        it.setMonthWeight(entity.getMonthWeight());
        it.setIsOld(entity.getIsOld());
        it.setIsCompleted(false);
        it.setIsScheme(false);
        contractService.saveOrUpdate(it);
        if(entity.getContractFinanceDto()!=null){//财务信息
            if(id!=null){//编辑前先删除之前数据
                contractFinanceService.deltedDate(id);
            }
            ContractFinanceDto contractFinanceDto = entity.getContractFinanceDto();
            ContractFinance contractFinance = new ContractFinance();
            contractFinance.setCurrency(contractFinanceDto.getCurrency());
            contractFinance.setPaymentType(contractFinanceDto.getPaymentType());
            contractFinance.setAccount(contractFinanceDto.getAccount());
            contractFinance.setAccountUuid(contractFinanceDto.getAccountUuid());
            contractFinance.setPaymentState(contractFinanceDto.getPaymentState());
            contractFinance.setDeliveryDate(contractFinanceDto.getDeliveryDate());
            contractFinance.setPaymentDate(contractFinanceDto.getPaymentDate());
            contractFinance.setEarnestMoneyProportion(contractFinanceDto.getEarnestMoneyProportion());
            contractFinance.setEarnestMoney(contractFinanceDto.getEarnestMoney());
            contractFinance.setContractUuid(it.getUuid());
            contractFinance.setAddUserName(user.getNickName());
            contractFinance.setAddUserUuid(user.getId());
            contractFinance.setDeleted(false);
            contractFinanceService.saveOrUpdate(contractFinance);
        }
        if(entity.getContractPendingOrderDto()!=null){//点价信息
            if(id!=null){//编辑前先删除之前数据
                contractPendingOrderService.deltedDate(id);
            }
            ContractPendingOrderDto contractPendingOrderDto = entity.getContractPendingOrderDto();
            ContractPendingOrder contractPendingOrder = new ContractPendingOrder();
            contractPendingOrder.setInstrumentUuid(contractPendingOrderDto.getInstrumentUuid());
            contractPendingOrder.setInstrumentCode(contractPendingOrderDto.getInstrumentCode());
            contractPendingOrder.setDeadline(contractPendingOrderDto.getDeadline());
            contractPendingOrder.setContractUuid(it.getUuid());
            contractPendingOrder.setAdvName(contractPendingOrderDto.getAdvName());
            contractPendingOrder.setAdvPhone(contractPendingOrderDto.getAdvPhone());
            contractPendingOrder.setAdvLinkmanUuid(contractPendingOrderDto.getAdvLinkmanUuid());
            contractPendingOrder.setName(contractPendingOrderDto.getName());
            contractPendingOrder.setPhone(contractPendingOrderDto.getPhone());
            contractPendingOrder.setLinkmanUuid(contractPendingOrderDto.getLinkmanUuid());
            contractPendingOrder.setDeleted(false);
            contractPendingOrder.setAddTime(new Date());
            contractPendingOrderService.saveOrUpdate(contractPendingOrder);
        }
        if(entity.getContractStorageDto()!=null){//仓储信息
            if(id!=null){//编辑前先删除之前数据
                contractStorageService.deltedDate(id);
            }
            ContractStorageDto contractStorageDto = entity.getContractStorageDto();
            ContractStorage contractStorage = new ContractStorage();
            contractStorage.setDeliveryPick(contractStorageDto.getDeliveryPick());
            contractStorage.setDeliveryHome(contractStorageDto.getDeliveryHome());
            contractStorage.setDeliveryTransfer(contractStorageDto.getDeliveryTransfer());
            contractStorage.setDeliveryFactory(contractStorageDto.getDeliveryFactory());
            contractStorage.setMoreOl(contractStorageDto.getMoreOl());
            contractStorage.setWeightDifference(contractStorageDto.getWeightDifference());
            contractStorage.setTransportBear(contractStorageDto.getTransportBear());
            contractStorage.setTransportPrice(contractStorageDto.getTransportPrice());
            contractStorage.setOutWarehouseBear(contractStorageDto.getOutWarehouseBear());
            contractStorage.setWarehousePrice(contractStorageDto.getWarehousePrice());
            contractStorage.setStorageBear(contractStorageDto.getStorageBear());
            contractStorage.setStoragePrice(contractStorageDto.getStoragePrice());
            contractStorage.setAddUserName(user.getNickName());
            contractStorage.setAddUser(user.getId());
            contractStorage.setContractUuid(it.getUuid());
            contractStorage.setDeleted(false);
            contractStorageService.saveOrUpdate(contractStorage);
        }
        if(id != null){//编辑时，不管前端传不传都要删除套保方案，合同变了套保方案也应该变化
            ContractSchemaDto contractSchemaDto = new ContractSchemaDto();
            contractSchemaDto.setContractUuid(id);
            List<ContractSchema> list = contractSchemaService.list(1, contractSchemaDto);
            if(list.size()>0) {
                Long hedgingUuid = list.get(0).getSchemaUuid();
                hedgingSchemeService.removeById(hedgingUuid);
                hedgingSchemeInstService.deltedDate(hedgingUuid);
                hedgeSchemeAccountService.deltedDate(hedgingUuid);
                contractSchemaService.deltedDate(hedgingUuid);
            }
        }
        if(entity.getHedgingSchemeDto()!=null){//套保方案
            HedgingSchemeDto hedgingSchemeDto = entity.getHedgingSchemeDto();
            HedgingScheme hedgingScheme = new HedgingScheme();
            hedgingScheme.setIsShow(false);
            hedgingScheme.setBizOrgName(it.getBizOrgName());
            hedgingScheme.setBizOrgUuid(it.getBizOrgUuid());
            hedgingScheme.setName(hedgingSchemeDto.getName());
            hedgingScheme.setBusinessType(hedgingSchemeDto.getBusinessType());
            hedgingScheme.setSalesmanName(hedgingSchemeDto.getSalesmanName());
            hedgingScheme.setMaturityDate(hedgingSchemeDto.getMaturityDate());
            hedgingScheme.setSalesmanUuid(hedgingSchemeDto.getSalesmanUuid());
            hedgingScheme.setTraderName(hedgingSchemeDto.getTraderName());
            hedgingScheme.setTraderUuid(hedgingSchemeDto.getTraderUuid());
            hedgingScheme.setRiskName(hedgingSchemeDto.getRiskName());
            hedgingScheme.setRiskUuid(hedgingSchemeDto.getRiskUuid());
            hedgingScheme.setExecutingState(hedgingSchemeDto.getExecutingState());
            hedgingScheme.setRemark(hedgingSchemeDto.getRemark());
            hedgingScheme.setCatalog(hedgingSchemeDto.getCatalog());
            hedgingScheme.setProduct(hedgingSchemeDto.getProduct());
            hedgingScheme.setInstrumentCode(hedgingSchemeDto.getInstrumentCode());
            hedgingScheme.setMaxPosition(hedgingSchemeDto.getMaxPosition());
            hedgingScheme.setSpotWeight(hedgingSchemeDto.getSpotWeight());
            hedgingScheme.setProfit(hedgingSchemeDto.getProfit());
            hedgingScheme.setClientProfit(hedgingSchemeDto.getClientProfit());
            hedgingScheme.setCheckTime(hedgingSchemeDto.getCheckTime());
            hedgingScheme.setCheckUserName(hedgingSchemeDto.getCheckUserName());
            hedgingScheme.setCheckUserUuid(hedgingSchemeDto.getCheckUserUuid());
            hedgingScheme.setDeleted(false);
            hedgingScheme.setAddUserName(user.getNickName());
            hedgingScheme.setAddTime(new Date());
            hedgingScheme.setAddUserUuid(user.getId());
            hedgingSchemeService.saveOrUpdate(hedgingScheme);
            if(hedgingSchemeDto.getHedgingSchemeInstDtos()!=null&&hedgingSchemeDto.getHedgingSchemeInstDtos().size()>0) {//套保合约明细
                List<HedgingSchemeInstDto> hedgingSchemeInstDtos = hedgingSchemeDto.getHedgingSchemeInstDtos();
                List<HedgingSchemeInst> hedgingSchemeInsts = new ArrayList<>();
                for (HedgingSchemeInstDto its : hedgingSchemeInstDtos) {
                    HedgingSchemeInst hedgingSchemeInst = new HedgingSchemeInst();
                    hedgingSchemeInst.setInstrumentCode(its.getInstrumentCode());
                    hedgingSchemeInst.setInstrumentUuid(its.getInstrumentUuid());
                    hedgingSchemeInst.setProductName(its.getProductName());
                    hedgingSchemeInst.setProductUuid(its.getProductUuid());
                    hedgingSchemeInst.setDirection(its.getDirection());
                    hedgingSchemeInst.setMaxPosition(its.getMaxPosition());
                    hedgingSchemeInst.setPositionType(its.getPositionType());
                    hedgingSchemeInst.setMaxPrice(its.getMaxPrice());
                    hedgingSchemeInst.setMinPrice(its.getMinPrice());
                    hedgingSchemeInst.setPriceType(its.getPriceType());
                    hedgingSchemeInst.setPrice(its.getPrice());
                    hedgingSchemeInst.setVolumeMultiple(its.getVolumeMultiple());
                    hedgingSchemeInst.setSchemeUuid(hedgingScheme.getUuid());
                    hedgingSchemeInst.setAddUserName(user.getNickName());
                    hedgingSchemeInst.setAddUserUuid(user.getId());
                    hedgingSchemeInst.setAddTime(new Date());
                    hedgingSchemeInst.setDeleted(false);
                    hedgingSchemeInsts.add(hedgingSchemeInst);
                }
                hedgingSchemeInstService.saveOrUpdateBatch(hedgingSchemeInsts);
            }

            if(hedgingSchemeDto.getHedgeSchemeAccountDtos()!=null&&hedgingSchemeDto.getHedgeSchemeAccountDtos().size()>0){
                List<HedgeSchemeAccount> hedgeSchemeAccounts = new ArrayList<>();
                List<HedgeSchemeAccountDto> hedgeSchemeAccountDtos = hedgingSchemeDto.getHedgeSchemeAccountDtos();
                for(HedgeSchemeAccountDto its : hedgeSchemeAccountDtos){
                    HedgeSchemeAccount hedgeSchemeAccount = new HedgeSchemeAccount();
                    hedgeSchemeAccount.setCtpUuid(its.getCtpUuid());
                    hedgeSchemeAccount.setSchemeUuid(hedgingScheme.getUuid());
                    hedgeSchemeAccount.setAddUserName(entity.getAddUserName());
                    hedgeSchemeAccount.setAddUserUuid(entity.getAddUserUuid());
                    hedgeSchemeAccount.setDeleted(false);
                    hedgeSchemeAccount.setAddTime(new Date());
                    hedgeSchemeAccounts.add(hedgeSchemeAccount);
                }
                hedgeSchemeAccountService.saveOrUpdateBatch(hedgeSchemeAccounts);
            }
            ContractSchema contractSchema = new ContractSchema();
            contractSchema.setAddUserName(user.getNickName());
            contractSchema.setAddUserUuid(user.getId());
            contractSchema.setContractUuid(it.getUuid());
            contractSchema.setSchemaUuid(hedgingScheme.getUuid());
            contractSchema.setDeleted(false);
            contractSchema.setAddTime(new Date());
            contractSchemaService.saveOrUpdate(contractSchema);

        }
        if(entity.getContractDetailDtos()!=null&&entity.getContractDetailDtos().size()>0){//合同明细
            List<ContractDetailDto> contractDetailDtos = entity.getContractDetailDtos();
            if(id!=null&&contractDetailDtos.size()>0){//编辑前先删除之前数据
                contractDetailService.deltedDate(id);
                ContractDetailRecordDto contractDetailRecordDto = new ContractDetailRecordDto();
                contractDetailRecordDto.setSourceContractUuid(id);
                List<ContractDetailRecord> contractDetailRecords = contractDetailRecordService.list(0, contractDetailRecordDto);
                for(ContractDetailRecord con : contractDetailRecords){//还原明细表数据
                    if(con.getSourceContractType().intValue()==1){//如果是销售发起修改采购数据
                        ContractDetail contractDetail1 = contractDetailService.getById(con.getPurchaseDetailUuid());
                        contractDetail1.setFrozenWeight(DecimalUtil.valueOf(contractDetail1.getFrozenWeight()).subtract(con.getWeight()).doubleValue());
                        contractDetailService.saveOrUpdate(contractDetail1);
                    }else {
                        ContractDetail contractDetail1 = contractDetailService.getById(con.getSaleDetailUuid());
                        contractDetail1.setFrozenWeight(DecimalUtil.valueOf(contractDetail1.getFrozenWeight()).subtract(con.getWeight()).doubleValue());
                        contractDetailService.saveOrUpdate(contractDetail1);
                    }
                }
                contractDetailRecordService.deltedDate(id);//删除发起合同明细数据
            }
            for(ContractDetailDto its:contractDetailDtos) {
                ContractDetail contractDetail = new ContractDetail();
                contractDetail.setMaterialSpotName(its.getMaterialSpotName());
                contractDetail.setMaterialSpotUuid(its.getMaterialSpotUuid());
                contractDetail.setTempPrice(its.getTempPrice());
                contractDetail.setMaterialCatalogName(its.getMaterialCatalogName());
                contractDetail.setMaterialCatalogUuid(its.getMaterialCatalogUuid());
                contractDetail.setStandards(its.getStandards());
                contractDetail.setQuality(its.getQuality());
                contractDetail.setProducer(its.getProducer());
                contractDetail.setWeightType(its.getWeightType());
                contractDetail.setWeight(its.getWeight());
                contractDetail.setSpotOpen(its.getWeight());
                contractDetail.setDiscount(its.getDiscount());
                contractDetail.setContractPrice(its.getContractPrice());
                contractDetail.setContractMoney(its.getContractMoney());
                contractDetail.setMatchedWeight(0d);
                contractDetail.setFrozenWeight(0d);
                contractDetail.setAddUserName(user.getNickName());
                contractDetail.setAddUserUuid(user.getId());
                contractDetail.setContractUuid(it.getUuid());
                contractDetail.setDicUuid(its.getDicUuid());
                contractDetail.setDicName(its.getDicName());
                contractDetail.setDeleted(false);
                contractDetail.setAddTime(new Date());
                contractDetailService.saveOrUpdate(contractDetail);
                Double operationWeight = 0d;
                if(its.getContractDetails()!=null&&its.getContractDetails().size()>0){//合同对应关系
                    List<ContractDetailDto> contractDetailDtoList = its.getContractDetails();
                    List<ContractDetailRecord> contractDetailRecords = new ArrayList<>();
                    List<ContractDetail> contractDetails = new ArrayList<>();
                    for(ContractDetailDto dto:contractDetailDtoList){
                        ContractDetail detail1 = contractDetailService.getById(dto.getUuid());
                        if(dto.getOperationWeight().doubleValue()> DecimalUtil.valueOf(detail1.getWeight()).subtract(detail1.getFrozenWeight()).doubleValue()){
                            throw new IllegalArgumentException("此明细的可用重量小于"+dto.getOperationWeight());
                        }
                        detail1.setFrozenWeight(DecimalUtil.valueOf(dto.getOperationWeight()).add(detail1.getFrozenWeight()).doubleValue());
                        contractDetails.add(detail1);
                        ContractDetailRecord contractDetailRecord = new ContractDetailRecord();
                        contractDetailRecord.setAddUserUuid(user.getId());
                        contractDetailRecord.setAddUserName(user.getNickName());
                        contractDetailRecord.setDeleted(false);
                        if(it.getIsContract()) {
                            contractDetailRecord.setPurchaseDetailUuid(dto.getUuid());
                            contractDetailRecord.setSaleDetailUuid(contractDetail.getUuid());
                        }else {
                            contractDetailRecord.setPurchaseDetailUuid(contractDetail.getUuid());
                            contractDetailRecord.setSaleDetailUuid(dto.getUuid());
                        }
                        contractDetailRecord.setSourceContractUuid(it.getUuid());
                        contractDetailRecord.setSourceContractType(it.getIsContract()?1:0);
                        contractDetailRecord.setWeight(dto.getOperationWeight());
                        contractDetailRecord.setAddTime(new Date());
                        contractDetailRecords.add(contractDetailRecord);
                        operationWeight=operationWeight+dto.getOperationWeight();
                    }
                    if(operationWeight>0){
                        contractDetail.setFrozenWeight(operationWeight);
                        contractDetailService.saveOrUpdate(contractDetail);
                    }
                    contractDetailService.saveOrUpdateBatch(contractDetails) ;
                    contractDetailRecordService.saveOrUpdateBatch(contractDetailRecords);
                }
            }
        }
        JSONResult<Contract> res = new JSONResult<>();
        res.setSuccess(true);
        res.setMessage("操作成功");
        res.setData(it);
        return res;
    }

    /**
     * 合同审批
     * @param user
     * @param entity
     * @return
     */
    @Override
    @Transactional
    public JSONResult<Contract> saveCheck(User user, ContractDto entity) {
        Contract contract = contractService.getById(entity.getUuid());
        if(contract.getCheckStatus().intValue()!=0){
            return JSONResult.getSimpleResult(false,"此合同不是未审批状态，不支持审批");
        }
        contract.setCheckStatus(entity.getCheckStatus());
        contract.setCheckTime(new Date());
        contract.setCheckUserUuid(user.getId());
        contract.setCheckUserName(user.getNickName());
        contract.setCheckExplain(entity.getCheckExplain());
        ContractDetailDto contractDetailDto = new ContractDetailDto();
        contractDetailDto.setContractUuid(contract.getUuid());
        List<ContractDetail> contractDetails = contractDetailService.list(0, contractDetailDto);//查询合同明细
        List<ContractDetail> contractDetailList = new ArrayList<>();
        for(ContractDetail it : contractDetails){
            ContractDetailRecordDto contractDetailRecordDto = new ContractDetailRecordDto();
            contractDetailRecordDto.setSourceContractUuid(contract.getUuid());
            Double operationWeight = 0d;
            if(contract.getIsContract()) {
                contractDetailRecordDto.setSaleDetailUuid(it.getUuid());
            }else {
                contractDetailRecordDto.setPurchaseDetailUuid(it.getUuid());
            }
            List<ContractDetailRecord> contractDetailRecords = contractDetailRecordService.list(0, contractDetailRecordDto);//查询匹配关系
            for(ContractDetailRecord its:contractDetailRecords){
                operationWeight=operationWeight+its.getWeight();
                ContractDetail contractDetail = contractDetailService.getById(contract.getIsContract()?its.getPurchaseDetailUuid():its.getSaleDetailUuid());
                contractDetail.setFrozenWeight(DecimalUtil.valueOf(contractDetail.getFrozenWeight()).subtract(its.getWeight()).doubleValue());
                if(entity.getCheckStatus().intValue()==1) {//审批通过才更新匹配重量
                    contractDetail.setMatchedWeight(DecimalUtil.valueOf(contractDetail.getMatchedWeight()).add(its.getWeight()).doubleValue());
                }
                contractDetailList.add(contractDetail);
            }
            it.setFrozenWeight(DecimalUtil.valueOf(it.getFrozenWeight()).subtract(operationWeight).doubleValue());
            if(entity.getCheckStatus().intValue()==1) {//审批通过
                it.setMatchedWeight(DecimalUtil.valueOf(it.getMatchedWeight()).add(operationWeight).doubleValue());
            }
        }
        ContractSchemaDto contractSchemaDto = new ContractSchemaDto();
        contractSchemaDto.setContractUuid(contract.getUuid());
        List<ContractSchema> list = contractSchemaService.list(1, contractSchemaDto);
        if(entity.getCheckStatus().intValue()==1){
            if(list.size()>0) {
                Long hedgingUuid = list.get(0).getSchemaUuid();
                HedgingScheme hedgingScheme = hedgingSchemeService.getById(hedgingUuid);
                hedgingScheme.setIsShow(true);
                hedgingSchemeService.saveOrUpdate(hedgingScheme);
            }
        }else {
            contractDetailRecordService.deltedDate(contract.getUuid());//删除发起合同匹配的关系
            //审批拒绝删除套保方案相关信息
            if(list.size()>0) {
                Long hedgingUuid = list.get(0).getSchemaUuid();
                hedgingSchemeService.removeById(hedgingUuid);
                hedgingSchemeInstService.deltedDate(hedgingUuid);
                hedgeSchemeAccountService.deltedDate(hedgingUuid);
                contractSchemaService.deltedDate(hedgingUuid);
            }
            contract.setIsScheme(false);
        }
        contractService.saveOrUpdate(contract);
        contractDetails.addAll(contractDetailList);
        contractDetailService.saveOrUpdateBatch(contractDetails);
        JSONResult<Contract> res = new JSONResult<>();
        res.setData(contract);
        res.setMessage("审批成功");
        res.setSuccess(true);
        return res;
    }

    /**
     * 采销匹配
     * @param user
     * @param entity
     * @return
     */
    @Override
    @Transactional
    public JSONResult<Contract> purchaseSaleMatching(User user, ContractDto entity) {
        Contract contract = contractService.getById(entity.getUuid());
        if(contract.getCheckStatus().intValue()!=1){
            return JSONResult.getSimpleResult(false,"合同不是已审批状态不支持此操作");
        }
        ContractDetailDto contractDetailDto1= new ContractDetailDto();
        contractDetailDto1.setContractUuid(entity.getUuid());
        List<ContractDetail> contractDetailDtos1 = contractDetailService.list(0,contractDetailDto1);
        for(ContractDetail its:contractDetailDtos1){//查出之前匹配关系
            ContractDetailRecordDto contractDetailRecordDto = new ContractDetailRecordDto();
            if(contract.getIsContract()) {
                contractDetailRecordDto.setSaleDetailUuid(its.getUuid());
            }else {
                contractDetailRecordDto.setPurchaseDetailUuid(its.getUuid());
            }
            List<ContractDetailRecord> contractDetailRecords = contractDetailRecordService.list(0, contractDetailRecordDto);
            Long[] ids=null ;
            Map<Long,ContractDetailRecord> contractDetailRecordMap = new HashMap<>();
            if(contract.getIsContract()) {//销售则根据采购分组
                if(contractDetailRecords.size()>0) {
                    ids = contractDetailRecords.stream().map(ContractDetailRecord::getPurchaseDetailUuid).toArray(Long[]::new);
                }
                contractDetailRecordMap=contractDetailRecords.stream().collect(Collectors.toMap(ContractDetailRecord::getPurchaseDetailUuid, Function.identity(),(a,b)->a));
            }else {//采购则根据销售分组
                if(contractDetailRecords.size()>0) {
                    ids = contractDetailRecords.stream().map(ContractDetailRecord::getSaleDetailUuid).toArray(Long[]::new);
                }
                contractDetailRecordMap=contractDetailRecords.stream().collect(Collectors.toMap(ContractDetailRecord::getSaleDetailUuid, Function.identity(),(a,b)->a));

            }
            if(ids!=null) {
                ContractDetailDto contractDetailDto = new ContractDetailDto();
                contractDetailDto.setIds(ids);
                List<ContractDetail> contractDetailList = contractDetailService.list(0, contractDetailDto);
                Double weight=0d;
                for (int i = 0; i < contractDetailList.size(); i++) {//还原之前重量
                    ContractDetail it = contractDetailList.get(i);
                    if (contractDetailRecordMap.containsKey(it.getUuid())) {
                        ContractDetailRecord contractDetailRecord = contractDetailRecordMap.get(it.getUuid());
                        it.setMatchedWeight(DecimalUtil.valueOf(it.getMatchedWeight()).subtract(contractDetailRecord.getWeight()).doubleValue());//还原对方的
                        weight= contractDetailRecord.getWeight()+weight;
                    }
                }
                its.setMatchedWeight(DecimalUtil.valueOf(its.getMatchedWeight()).subtract(weight).doubleValue());//还原自己的
                contractDetailList.add(its);
                contractDetailService.saveOrUpdateBatch(contractDetailList);
                for (ContractDetailRecord rec : contractDetailRecords) {//删除原来关系
                    contractDetailRecordService.removeById(rec.getId());
                }
            }
        }
        contractDetailService.saveOrUpdateBatch(contractDetailDtos1);
        List<ContractDetailDto> contractDetailDtos = entity.getContractDetailDtos();
        for(ContractDetailDto its:contractDetailDtos) {
            Double operationWeight = 0d;
            if (its.getContractDetails() != null && its.getContractDetails().size() > 0) {//合同对应关系
                List<ContractDetailDto> contractDetailDtoList = its.getContractDetails();
                List<ContractDetailRecord> contractDetailRecords = new ArrayList<>();
                List<ContractDetail> contractDetails = new ArrayList<>();
                for (ContractDetailDto dto : contractDetailDtoList) {
                    ContractDetail detail1 = contractDetailService.getById(dto.getUuid());
                    if (dto.getOperationWeight().doubleValue() > DecimalUtil.valueOf(detail1.getWeight()).subtract(detail1.getFrozenWeight()).doubleValue()) {
                        throw new IllegalArgumentException("此明细的可用重量小于" + dto.getOperationWeight());
                    }
                    detail1.setMatchedWeight(DecimalUtil.valueOf(dto.getOperationWeight()).add(detail1.getFrozenWeight()).doubleValue());
                    contractDetails.add(detail1);
                    ContractDetailRecord contractDetailRecord = new ContractDetailRecord();
                    contractDetailRecord.setAddUserUuid(user.getId());
                    contractDetailRecord.setAddUserName(user.getNickName());
                    contractDetailRecord.setDeleted(false);
                    if (contract.getIsContract()) {
                        contractDetailRecord.setPurchaseDetailUuid(dto.getUuid());
                        contractDetailRecord.setSaleDetailUuid(its.getUuid());
                    } else {
                        contractDetailRecord.setPurchaseDetailUuid(its.getUuid());
                        contractDetailRecord.setSaleDetailUuid(dto.getUuid());
                    }
                    contractDetailRecord.setSourceContractUuid(entity.getUuid());
                    contractDetailRecord.setSourceContractType(contract.getIsContract() ? 1 : 0);
                    contractDetailRecord.setWeight(dto.getOperationWeight());
                    contractDetailRecords.add(contractDetailRecord);
                    operationWeight = operationWeight + dto.getOperationWeight();
                }
                contractDetailService.saveOrUpdateBatch(contractDetails);
                contractDetailRecordService.saveOrUpdateBatch(contractDetailRecords);
            }
            if(operationWeight>0){
                ContractDetail contractDetail = contractDetailService.getById(its.getUuid());
                contractDetail.setMatchedWeight(DecimalUtil.valueOf(contractDetail.getMatchedWeight()).add(operationWeight).doubleValue());
                if(contractDetail.getMatchedWeight().doubleValue()>contractDetail.getWeight().doubleValue()){
                    throw new IllegalArgumentException("匹配的总重量大于此条明细重量：" +contractDetail.getMatchedWeight()+"+"+operationWeight+">"+contractDetail.getWeight());
                }
            }
        }
        JSONResult<Contract> res = new JSONResult<>();
        res.setSuccess(true);
        res.setMessage("匹配成功");
        res.setData(contract);
        return res;
    }
}
